/*
 * @Author: wangzy
 * @Date: 2022-06-28 19:16:38
 * @LastEditors: wangzy
 * @LastEditTime: 2022-06-28 19:46:08
 * @Description: 观察者模式
 */
/***
 * 观察者模式定义了一种一对多的依赖关系，
 * 让多个观察者对象同时监听某一个目标对象，
 * 当这个目标对象的状态发生变化时，
 * 会通知所有观察者对象，使它们能够自动更新。
 */
// 定义发布者类
class Publisher {
  constructor() {
    this.observers = []
    console.log('Publisher created')
  }
  // 增加订阅者
  add(observer) {
    console.log('Publisher.add invoked')
    this.observers.push(observer)
  }
  // 移除订阅者
  remove(observer) {
    console.log('Publisher.remove invoked')
    this.observers.forEach((item, i) => {
      if (item === observer) {
        this.observers.splice(i, 1)
      }
    })
  }
  // 通知所有订阅者
  notify() {
    console.log('Publisher.notify invoked')
    this.observers.forEach((observer) => {
      observer.update(this)
    })
  }
}
// 定义监听者类
class Observer {
  constructor() {
    console.log('Observer created')
  }

  update() {
    console.log('Observer.update invoked')
  }
}
// 定义一个具体的需求文档（prd）发布类
class PrdPublisher extends Publisher {
  constructor() {
    super()
    // 初始化需求文档
    this.prdState = null
    // 韩梅梅还没有拉群，开发群目前为空
    this.observers = []
    console.log('PrdPublisher created')
  }
  // 该方法用于获取当前的prdState
  getState() {
    console.log('PrdPublisher.getState invoked')
    return this.prdState
  }
  // 该方法用于改变prdState的值
  setState(state) {
    console.log('PrdPublisher.setState invoked')
    // prd的值发生改变
    this.prdState = state
    // 需求文档变更，立刻通知所有开发者
    this.notify()
  }
}
class DeveloperObserver extends Observer {
  constructor() {
    super()
    // 需求文档一开始还不存在，prd初始为空对象
    this.prdState = {}
    console.log('DeveloperObserver created')
  }
  // 重写一个具体的update方法
  update(publisher) {
    console.log('DeveloperObserver.update invoked')
    // 更新需求文档
    this.prdState = publisher.getState()
    // 调用工作函数
    this.work()
  }
  // work方法，一个专门搬砖的方法
  work() {
    // 获取需求文档
    const prd = this.prdState
    // 开始基于需求文档提供的信息搬砖。。。
    console.log('996 begins...', prd)
  }
}

const wangzy = new DeveloperObserver()
// const cuiy = new DeveloperObserver()
// const liuh = new DeveloperObserver()
const hanMeiMei = new PrdPublisher()
const prd = {
  msg: '花有重开日, 人无再少年',
}
hanMeiMei.add(wangzy)
// hanMeiMei.add(cuiy)
// hanMeiMei.add(liuh)
hanMeiMei.setState(prd)
